package com.micro.school.order.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.micro.school.common.core.constant.CacheConstants;
import com.micro.school.common.core.constant.Constants;
import com.micro.school.common.core.constant.PayConstants;
import com.micro.school.common.core.context.SecurityContextHolder;
import com.micro.school.common.core.domain.R;
import com.micro.school.common.core.utils.StringUtils;
import com.micro.school.common.core.web.domain.AjaxResult;
import com.micro.school.common.redis.service.RedisService;
import com.micro.school.common.security.utils.SecurityUtils;
import com.micro.school.order.bo.GenerateBillBo;
import com.micro.school.order.bo.PayStudentFeeBo;
import com.micro.school.order.bo.PayStudentFeeItemBo;
import com.micro.school.order.entity.*;
import com.micro.school.order.mapper.PayStudentFeeItemMapper;
import com.micro.school.order.mapper.PayStudentFeeMapper;
import com.micro.school.order.service.IPayFeeItemConfigService;
import com.micro.school.order.service.IPayStandardFeeItemDetailService;
import com.micro.school.order.service.IPayStandardFeeItemService;
import com.micro.school.order.service.IPayStudentFeeService;
import com.micro.school.order.util.OrderNoGenerator;
import com.micro.school.order.vo.PayStandardFeeItemDetailVo;
import com.micro.school.order.vo.PayStandardFeeItemVo;
import com.micro.school.order.vo.PayStudentFeeItemVo;
import com.micro.school.system.api.RemoteEduService;
import com.micro.school.system.api.RemoteUserService;
import com.micro.school.system.api.domain.StudentInfos;
import com.micro.school.system.api.domain.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.micro.school.order.vo.PayStudentFeeVo;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;
/**
 * 学生收费管理Service业务层处理
 * 
 * @author lyb
 * @date 2025-08-16
 */
@Service
@Slf4j
public class PayStudentFeeServiceImpl implements IPayStudentFeeService
{
    @Autowired
    private PayStudentFeeMapper payStudentFeeMapper;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private IPayStandardFeeItemService payStandardFeeItemService;
    @Autowired
    private PayStudentFeeItemMapper payStudentFeeItemMapper;

    @Autowired
    private IPayStandardFeeItemDetailService itemDetailService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private RemoteEduService eduService;

    @Autowired
    private IPayFeeItemConfigService itemConfigService;

    /**
     * 查询学生收费管理
     * 
     * @param id 学生收费管理主键
     * @return 学生收费管理
     */
    @Override
    public PayStudentFeeVo selectPayStudentFeeById(Long id)
    {
        PayStudentFeeVo feeVo = payStudentFeeMapper.selectPayStudentFeeById(id);
        if (1 == SecurityContextHolder.getUserIdcardState()){
            if (feeVo.getIdNumber() != null && feeVo.getIdNumber().length() > 8) {
                String maskedIdNumber = feeVo.getIdNumber().substring(0, feeVo.getIdNumber().length() - 8) + "********";
                feeVo.setIdNumber(maskedIdNumber);
            } else if (feeVo.getIdNumber() != null) {
                feeVo.setIdNumber(feeVo.getIdNumber().replaceAll(".", "*"));
            }
        }
        List<PayStudentFeeItemVo> itemVos = queryDetailsByStudentFeeId(id);
        feeVo.setDetails(itemVos);
        return feeVo;
    }

    /**
     * 根据主表（学生收费）主键查询
     */
    @Override
    public List<PayStudentFeeItemVo> queryDetailsByStudentFeeId(Long studentFeeId){
       return payStudentFeeItemMapper.queryByStudentFeeId(studentFeeId);
    }

    /**
     * 查询学生收费管理列表
     * 
     * @param payStudentFee 学生收费管理
     * @return 学生收费管理
     */
    @Override
    public List<PayStudentFeeVo> selectPayStudentFeeList(PayStudentFeeBo payStudentFee)
    {
        List<PayStudentFeeVo> payStudentFeeVos = payStudentFeeMapper.selectPayStudentFeeList(payStudentFee);
        if (SecurityContextHolder.getUserIdcardState() != null){
            if (1 == SecurityContextHolder.getUserIdcardState()){
                payStudentFeeVos.forEach(vo -> {
                    if (vo.getIdNumber() != null && vo.getIdNumber().length() > 8) {
                        String maskedIdNumber = vo.getIdNumber().substring(0, vo.getIdNumber().length() - 8) + "********";
                        vo.setIdNumber(maskedIdNumber);
                    } else if (vo.getIdNumber() != null) {
                        vo.setIdNumber(vo.getIdNumber().replaceAll(".", "*"));
                    }
                });
            }
        }
        return payStudentFeeVos;
    }

    /**
     * 新增学生收费管理
     * 
     * @param payStudentFee 学生收费管理
     * @return 结果
     */
    @Override
    public int insertPayStudentFee(PayStudentFee payStudentFee)
    {
        return payStudentFeeMapper.insertPayStudentFee(payStudentFee);
    }

    /**
     * 新增学生收费管理
     *
     * @param payStudentFeeBo 学生收费管理
     * @return 结果
     */
    @Override
    public AjaxResult insertPayStudentFee(PayStudentFeeBo payStudentFeeBo){
        if(StringUtils.isEmpty(payStudentFeeBo.getIdNumber())){
            return AjaxResult.error("请输入身份证号码");
        }
        StudentInfoVos studentQuery = new StudentInfoVos();
        studentQuery.setIdNumber(payStudentFeeBo.getIdNumber());
        R<StudentInfos> studentR = remoteUserService.queryStudent(studentQuery);
        if(null==studentR || studentR.getData()==null){
            return AjaxResult.error(payStudentFeeBo.getIdNumber()+"该学生不存在");
        }
        StudentInfos student = studentR.getData();
        if(null==student || student.getId()==null){
            return AjaxResult.error(payStudentFeeBo.getIdNumber()+"该学生不存在");
        }
        PayStudentFee payStudentFee = JSON.parseObject(JSON.toJSONString(payStudentFeeBo), PayStudentFee.class);
        List<PayStudentFeeItemBo> itemBos = payStudentFeeBo.getDetails();
        if(null==itemBos || itemBos.isEmpty()){
            return AjaxResult.error(payStudentFeeBo.getIdNumber()+"费用明细不能为空");
        }
        payStudentFee.setBillNo(OrderNoGenerator.generateOrderNo());
        if(null!=payStudentFeeBo.getCampusId()){
            payStudentFee.setCampusId(payStudentFeeBo.getCampusId().longValue());
        }

        //设置一些字段的名称
        setNames(payStudentFee);
        List<PayStudentFeeItem> items = JSON.parseArray(
                JSON.toJSONString(itemBos),
                PayStudentFeeItem.class
        );
        Map<Long, PayFeeItemConfig> configMap = itemConfigService.queryToMap(SecurityUtils.getIntTenantId());
        for(PayStudentFeeItem item:items){
            item.setDeleteFlag(PayConstants.DEL_STR_0);
            item.setCreateDept(payStudentFeeBo.getCreateDept());
            item.setCreateBy(payStudentFeeBo.getCreateBy());
            item.setCreateTime(new Date());
            item.setUpdateBy(payStudentFeeBo.getUpdateBy());
            item.setUpdateTime(new Date());
            item.setBillNo(payStudentFee.getBillNo());
            if(null==item.getItemQuantity()){
                item.setItemQuantity(1);
            }
            item.setTotalAmount(item.getItemPrice());
            PayFeeItemConfig config = null;
            if(null!=item.getFeeItemConfigId()){
                config = configMap.get(item.getFeeItemConfigId().longValue());
            }
            if(null!=config){
                item.setMandatoryStatus(config.getMandatoryStatus());
                item.setFeeItemConfigType(config.getSubjectType());
                if(null!=config.getOrderNum()){
                    item.setOrderNum(config.getOrderNum().intValue());
                }
                item.setFeeItemConfigType(config.getSubjectType());
            }
            item.setPayStatus(PayConstants.PAYSTATUS_10);
        }
        GenerateBillEntity billEntity = new GenerateBillEntity();
        billEntity.setStudentFee(payStudentFee);
        billEntity.setFeeItems(items);
        List<GenerateBillEntity> entities = new ArrayList<>();
        entities.add(billEntity);
        //保存一批学生收费信息
        List<StudentInfos> studentInfos = new ArrayList<>();
        studentInfos.add(student);
        Map<Integer,List<PayStudentFeeVo>> feeMap = getPayStudentFeeVoMapByStudentId(studentInfos);
        return saveStudentFee(entities,feeMap);
    }

    private void setNames(PayStudentFee item){
        //设置year名
        if(null!=item.getFeeYearId()){
            R<SchoolFeeYearVos> feeYearR = eduService.getYearById(item.getFeeYearId().longValue());
            if(null!=feeYearR && null!=feeYearR.getData()){
                SchoolFeeYearVos feeYear = feeYearR.getData();
                if(null!=feeYear){
                    item.setFeeYear(feeYear.getFeeYear());
                }
            }
        }

        //学院名
        if(null!=item.getCollegeId()){
            R<SchoolCollegeVos> beanR = eduService.getCollegeById(item.getCollegeId());
            if(null!=beanR && null!=beanR.getData()){
                SchoolCollegeVos bean = beanR.getData();
                if(null!=bean){
                    item.setCollegeName(bean.getCollegeName());
                }
            }
        }

        //学院模式
        if(null!=item.getModelId()){
            R<CollegeModelVos> beanR = eduService.getModelById(item.getModelId());
            if(null!=beanR && null!=beanR.getData()){
                CollegeModelVos bean = beanR.getData();
                if(null!=bean){
                    item.setModelName(bean.getModelName());
                }
            }
        }

        //校区信息
        if(null!=item.getCampusId()){
            R<SchoolCampusVos> beanR = eduService.getCampusById(item.getCampusId());
            if(null!=beanR && null!=beanR.getData()){
                SchoolCampusVos bean = beanR.getData();
                if(null!=bean){
                    item.setCampusName(bean.getCampusName());
                }
            }
        }

        //专业
        if(null!=item.getMajorId()){
            R<CollegeMajorVos> majorR= eduService.getMajorById(item.getMajorId());
            if(null!=majorR && null!=majorR.getData()){
                CollegeMajorVos bean = majorR.getData();
                if(null!=bean){
                    item.setMajorName(bean.getMajorName());
                }
            }
        }
        //学校收费学年
        if(null!=item.getFeeYearId()){
            R<SchoolFeeYearVos> beanR = eduService.getYearById(item.getFeeYearId().longValue());
            if(null!=beanR && null!=beanR.getData()){
                SchoolFeeYearVos bean = beanR.getData();
                if(null!=bean){
                    item.setFeeYear(bean.getFeeYear());
                }
            }
        }
        //学校年级
        if(null!=item.getGradeId()){
            R<SchoolGradeVos> beanR = eduService.getGradeById(item.getGradeId());
            if(null!=beanR && null!=beanR.getData()){
                SchoolGradeVos bean = beanR.getData();
                if(null!=bean){
                    item.setGradeName(bean.getGrade());
                }
            }
        }
    }
    /**
     * 修改学生收费管理
     * 
     * @param payStudentFee 学生收费管理
     * @return 结果
     */
    @Override
    public int updatePayStudentFee(PayStudentFee payStudentFee)
    {
        return payStudentFeeMapper.updatePayStudentFee(payStudentFee);
    }

    /**
     * 批量删除学生收费管理
     *
     * @param ids 需要删除的学生收费管理主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deletePayStudentFeeByIds(Long[] ids)
    {
        for(Long id:ids){
            payStudentFeeItemMapper.deleteByStudentFeeId(id);
        }
        return payStudentFeeMapper.deletePayStudentFeeByIds(ids);
    }

    /**
     * 删除学生收费管理信息
     * 
     * @param id 学生收费管理主键
     * @return 结果
     */
    @Override
    public int deletePayStudentFeeById(Long id)
    {
        return payStudentFeeMapper.deletePayStudentFeeById(id);
    }
    @Override
    public int deletePayStudentFeeById(PayStudentFee studentFee)
    {
        PayStudentFeeVo studentFeeQuery = selectPayStudentFeeById(studentFee.getId().longValue());
        if(studentFeeQuery==null){
            return 0;
        }
        if(studentFeeQuery.getStudentId().intValue()!=studentFee.getStudentId().intValue()){
            return 0;
        }
        return payStudentFeeMapper.deletePayStudentFeeById(studentFee.getId().longValue());
    }



    /**
     * 根据学生ID查询
     */
    @Override
    public List<PayStudentFeeVo> listByStudentIds(List<Long> studentId){
        return payStudentFeeMapper.listByStudentIds(studentId);
    }

    @Override
    public PayStudentFeeVos getFeignOne(PayStudentFeeVos payStudentFeeVos) {
        List<PayStudentFeeVos> feignOne = payStudentFeeMapper.getFeignOne(payStudentFeeVos);
        if (feignOne != null && !feignOne.isEmpty()) {
            // 初始化总额
            BigDecimal totalAmountPayable = BigDecimal.ZERO;
            BigDecimal totalAmountPaid = BigDecimal.ZERO;
            BigDecimal totalAmountPending = BigDecimal.ZERO;

            // 遍历列表计算总额
            for (PayStudentFeeVos fee : feignOne) {
                if (fee.getAmountPayable() != null) {
                    totalAmountPayable = totalAmountPayable.add(new BigDecimal(fee.getAmountPayable()));
                }
                if (fee.getAmountPaid() != null) {
                    totalAmountPaid = totalAmountPaid.add(new BigDecimal(fee.getAmountPaid()));
                }
                if (fee.getAmountPending() != null) {
                    totalAmountPending = totalAmountPending.add(new BigDecimal(fee.getAmountPending()));
                }
            }

            // 将总额设置到返回对象中（这里使用第一个对象作为返回对象，仅更新金额字段）
            PayStudentFeeVos result = new PayStudentFeeVos();
            result.setAmountPayable(totalAmountPayable.doubleValue());
            result.setAmountPaid(totalAmountPaid.doubleValue());
            result.setAmountPending(totalAmountPending.doubleValue());

            return result;
        }
        return null;
    }

    @Override
    public Map<String, Map<String, Object>> getFeignFeeItemVo(PayStudentFeeVos payStudentFeeVos) {
        List<PayStudentFeeItemVos> list = payStudentFeeItemMapper.getFeignFeeItemVos(payStudentFeeVos);
        Map<String, Map<String, Object>> typeMap = new HashMap<>();
        for (PayStudentFeeItemVos payStudentFeeItemVos : list) {
            String feeItemConfigType = payStudentFeeItemVos.getFeeItemConfigType();
            BigDecimal total = payStudentFeeItemVos.getTotal();
            // 如果该类型还没有在map中，初始化
            if (!typeMap.containsKey(feeItemConfigType)) {
                Map<String, Object> statusMap = new HashMap<>();
                statusMap.put("paid", BigDecimal.ZERO);      // 已支付
                statusMap.put("unpaid", BigDecimal.ZERO);    // 未支付
                statusMap.put("actual", BigDecimal.ZERO);    // 实际支付
                typeMap.put(feeItemConfigType, statusMap);
            }
            Map<String, Object> statusMap = typeMap.get(feeItemConfigType);
            // 根据支付状态分类统计
            if (payStudentFeeItemVos.getPayStatus() == 30) { // 支付成功
                // 已支付和实际支付都增加
                statusMap.put("paid", ((BigDecimal) statusMap.get("paid")).add(total));
                statusMap.put("actual", ((BigDecimal) statusMap.get("actual")).add(total));

            } else if (payStudentFeeItemVos.getPayStatus() == 10) { // 待支付或支付中
                // 未支付增加
                statusMap.put("unpaid", ((BigDecimal) statusMap.get("unpaid")).add(total));
                statusMap.put("actual", ((BigDecimal) statusMap.get("actual")).add(total));
            }
            statusMap.put("studentFeeId", payStudentFeeItemVos.getId());
            // 其他状态(支付失败40, 已退款50)不计入统计
            statusMap.put("feeItemConfigId", payStudentFeeItemVos.getFeeItemConfigId());
        }
        return typeMap;
    }

    @Override
    public List<PayStudentFeeItemVos> queryStudentFeeItemDetails(PayStudentFeeVos payStudentFeeVos) {

        return payStudentFeeItemMapper.queryStudentFeeItemDetails(payStudentFeeVos);
    }

    @Override
    public List<PayStudentFeeVo> selectPayStudent(PayStudentFee payStudentFee) {
        return payStudentFeeMapper.selectPayStudent(payStudentFee);
    }

    @Override
    public int updateStudentFee(List<PayStudentFeePaymentDetailVos> payStudentFeePaymentVosDetails) {
        return payStudentFeeItemMapper.updateStudentFee(payStudentFeePaymentVosDetails);
    }

    @Override
    public PayStudentFeeVos queryStudentFeeByDetail(Long studentFeeId) {
        return payStudentFeeMapper.queryStudentFeeByDetail(studentFeeId);
    }

    @Override
    public BigDecimal sumStudentFee(Long studentFeeId) {
        return payStudentFeeMapper.sumStudentFee(studentFeeId);
    }

    @Override
    public void updateStudentFeeTotalMoney(PayStudentFeeVos payStudentFeeVos) {
        payStudentFeeMapper.updateStudentFeeTotalMoney(payStudentFeeVos);
    }

    @Override
    public void updateAllOrderCollegeName(String collegeName, Long collegeId) {
        payStudentFeeMapper.updateAllOrderCollegeName1(collegeName, collegeId);
        payStudentFeeMapper.updateAllOrderCollegeName2(collegeName, collegeId);
        payStudentFeeMapper.updateAllOrderCollegeName3(collegeName, collegeId);
        payStudentFeeMapper.updateAllOrderCollegeName4(collegeName, collegeId);
    }

    @Override
    public void updateAllCollegeMajor(String majorName, Long id) {
        payStudentFeeMapper.updateAllCollegeMajor1(majorName, id);
        payStudentFeeMapper.updateAllCollegeMajor2(majorName, id);
        payStudentFeeMapper.updateAllCollegeMajor3(majorName, id);
        payStudentFeeMapper.updateAllCollegeMajor4(majorName, id);
    }

    @Override
    public void updateAllCollegeModel(String modelName, Long id) {
        payStudentFeeMapper.updateAllCollegeModel1(modelName, id);
        payStudentFeeMapper.updateAllCollegeModel2(modelName, id);
        payStudentFeeMapper.updateAllCollegeModel3(modelName, id);
        payStudentFeeMapper.updateAllCollegeModel4(modelName, id);
    }

    @Override
    public void updateAllCampusName(String campusName, Long id) {
        payStudentFeeMapper.updateAllCampusName1(campusName, id);
        payStudentFeeMapper.updateAllCampusName2(campusName, id);
        payStudentFeeMapper.updateAllCampusName3(campusName, id);
        payStudentFeeMapper.updateAllCampusName4(campusName, id);
    }

    @Override
    public void updateAllFeeYear(String feeYear, Long id) {
        payStudentFeeMapper.updateAllFeeYear1(feeYear, id);
        payStudentFeeMapper.updateAllFeeYear2(feeYear, id);
        payStudentFeeMapper.updateAllFeeYear3(feeYear, id);
        payStudentFeeMapper.updateAllFeeYear4(feeYear, id);
    }

    /**
     * 生成账单
     */
    @Override
    public void generateBill(GenerateBillBo billBo){
        log.info(" start PayStudentFeeServiceImpl|generateBill {} ",JSON.toJSONString(billBo));
        Long feeItemId = billBo.getFeeItemId();
        log.info("查询标准费用 feeItemId {} ",feeItemId);
        PayStandardFeeItemVo feeItemVo = payStandardFeeItemService.selectPayStandardFeeItemById(feeItemId);
        if(null==feeItemVo){
            return;
        }
        //查询学生
        StudentInfos query = new StudentInfos();
        query.setId(-1L);
        query.setCollegeId(feeItemVo.getCollegeId());
        query.setMajorId(feeItemVo.getMajorId());
        query.setSchoolSystem(feeItemVo.getStudyPeriod());
        query.setGradeId(feeItemVo.getGradeId());
        query.setTenantId(feeItemVo.getTenantId());
        query.setIsDel(0);
        int currentYear = LocalDate.now().getYear();
        //是否是新生
        if(null!=feeItemVo.getGradeName()){
            boolean isNewStudent = feeItemVo.getGradeName().contains(currentYear+"");
            //如果是老生 只查询 在校生
            if(!isNewStudent){
                query.setGraduate(Constants.LONG_ONE);
            }
        }
        List<GenerateBillEntity> entities = new ArrayList<>();
        List<PayStandardFeeItemDetailVo> feeItemDetailVos = itemDetailService.selectPayStandardFeeItemDetailByFeeItemId(feeItemVo.getId());
        log.info("查询学生 {} ",JSON.toJSONString(query));
        R<List<StudentInfos>> studentsR = remoteUserService.listStudentLimitById(query);
        List<StudentInfos> studentInfos = studentsR.getData();
        Integer i=0;
        while (null!=studentInfos && !studentInfos.isEmpty()){
            i++;
            if(i>500){
                log.error("PayStudentFeeServiceImpl|generateBill 循环次数太多了，异常！ billBo={}",JSON.toJSONString(billBo));
                break;
            }
            log.info("查询学生数量 {} ",studentInfos.size());
            //处理查询的学生
            for(StudentInfos student:studentInfos){
                log.info("studentId {} ",student.getId());
                PayStudentFee studentFee = buildPayStudentFeeFromStudent(student,feeItemVo,billBo);
                GenerateBillEntity billEntity = new GenerateBillEntity();
                billEntity.setStudentFee(studentFee);
                billEntity.setFeeItems(buildPayStudentFeeItemFromStudent(student, studentFee, feeItemDetailVos,billBo));
                entities.add(billEntity);
                query.setId(student.getId());
            }
            //保存一批学生收费信息
            Map<Integer,List<PayStudentFeeVo>> feeMap = getPayStudentFeeVoMapByStudentId(studentInfos);
            saveStudentFee(entities,feeMap);
            entities.clear();

            //再次查询学生
            log.info("查询下一批学生 {} ",JSON.toJSONString(query));
            studentsR = remoteUserService.listStudentLimitById(query);
            studentInfos = studentsR.getData();
        }

        //修改状态为已生成
        PayStandardFeeItem update = new PayStandardFeeItem();
        update.setId(billBo.getFeeItemId());
        update.setGenerateStatus(PayConstants.GENERATESTATUS_1);
        update.setTenantId(feeItemVo.getTenantId());
        log.info(" 更新生成状态 billBo.getFeeItemId {} {} ",billBo.getFeeItemId(),PayConstants.GENERATESTATUS_1);
        payStandardFeeItemService.updatePayStandardFeeItem(update);
        //删除redis锁
        log.info(" 删除锁 billBo.getFeeItemId {} ");
        redisService.deleteObject(CacheConstants.GENERATEBILL_LOCK+billBo.getFeeItemId());
        log.info(" end PayStudentFeeServiceImpl|generateBill {} ",JSON.toJSONString(billBo));
    }

    private void fillFeeConfig(List<PayStudentFeeItem> items,Integer tenantId){
        if(null==items || items.isEmpty()){
            return;
        }
        Map<Long, PayFeeItemConfig> configMap = itemConfigService.queryToMap(tenantId);
        for(PayStudentFeeItem item:items){
            PayFeeItemConfig feeItemConfig = configMap.get(item.getFeeItemConfigId().longValue());
            if(null==feeItemConfig){
                continue;
            }
            item.setFeeItemConfigType(feeItemConfig.getSubjectType());
            item.setMandatoryStatus(feeItemConfig.getMandatoryStatus());
        }

    }
    private Map<Integer,String> getCampusName(List<StudentInfos> studentInfos){
        Map<Integer,String> compusNames = new HashMap<>();
        if(null==studentInfos){
            return compusNames;
        }
        for(StudentInfos infos:studentInfos){
            if(compusNames.containsKey(infos.getCompusId())){
                continue;
            }
            //校区信息
            if(null!=infos.getCompusId()){
                R<SchoolCampusVos> beanR = eduService.getCampusById(infos.getCompusId().longValue());
                if(null!=beanR && null!=beanR.getData()){
                    SchoolCampusVos bean = beanR.getData();
                    if(null!=bean){
                        compusNames.put(infos.getCompusId(),bean.getCampusName());
                    }
                }
            }
        }
        return compusNames;
    }

    @Transactional
    public AjaxResult saveStudentFee(List<GenerateBillEntity> entities, Map<Integer,List<PayStudentFeeVo>> feeMap){
        log.info("saveStudentFee");
        if(null==entities || entities.isEmpty()){
            return AjaxResult.error();
        }
        for(GenerateBillEntity entity:entities){
            log.info("GenerateBillEntity {}", JSON.toJSONString(entity));
            PayStudentFee studentFee = entity.getStudentFee();
            log.info("saveStudentFee 查询学生存在的账单 student {}", studentFee.getStudentId());
            PayStudentFeeVo feeVo = entity.match(feeMap.get(studentFee.getStudentId()));
            //如果存在
            if(null!=feeVo){
                //已支付返回
                boolean isBillPay = !(PayConstants.BILLSTATUS_10.equals(feeVo.getBillStatus())) && !(PayConstants.BILLSTATUS_40.equals(feeVo.getBillStatus()));
                if(isBillPay){
                    log.info("saveStudentFee 账单已支付 student {} PayStudentFeeVo {} 返回", studentFee.getStudentId(),feeVo.getId());
                    return AjaxResult.error("账单已支付 不允许新增");
                }
                //未支付删除
                log.info("删除账单 PayStudentFeeVo {} ", feeVo.getId());
                deletePayStudentFeeById(feeVo.getId().longValue());
                payStudentFeeItemMapper.deleteByStudentFeeId(feeVo.getId().longValue());
            }
            //新增
            log.info("新增单 PayStudentFee");
            entity.setAmount();
            insertPayStudentFee(studentFee);
            log.info("新增单 PayStudentFee id = {}" ,studentFee.getId());
            entity.setFeeItemFeeId();
            entity.setTenantId();
            List<PayStudentFeeItem> feeItems = entity.getFeeItems();
            if(null!=feeItems){
                //设置费用配置
                fillFeeConfig(feeItems,studentFee.getTenantId());
                payStudentFeeItemMapper.insertBatch(feeItems);
            }
        }
        return AjaxResult.success();
    }

    private PayStudentFee buildPayStudentFeeFromStudent(StudentInfos student,PayStandardFeeItemVo feeItemVo,GenerateBillBo billBo){
        PayStudentFee fee = new PayStudentFee();
        fee.setBillNo(OrderNoGenerator.generateOrderNo());
        fee.setStudentId(student.getId().intValue());
        fee.setStudentName(student.getName());
        fee.setIdNumber(student.getIdNumber());
        fee.setCampusId(feeItemVo.getCampusId());
        fee.setCampusName(feeItemVo.getCampusName());
        fee.setCollegeId(feeItemVo.getCollegeId());
        fee.setCollegeName(feeItemVo.getCollegeName());
        fee.setModelId(feeItemVo.getModelId());
        fee.setModelName(feeItemVo.getModelName());
        fee.setMajorId(feeItemVo.getMajorId());
        fee.setMajorName(feeItemVo.getMajorName());
        fee.setStudyPeriod(feeItemVo.getStudyPeriod());
        fee.setGradeId(feeItemVo.getGradeId());
        fee.setGradeName(feeItemVo.getGradeName());
        fee.setFeeYearId(feeItemVo.getFeeYearId());
        fee.setFeeYear(feeItemVo.getFeeYear());
        if(null!=feeItemVo.getTotalAmount()){
            fee.setAmountPayable(feeItemVo.getTotalAmount().doubleValue());
            fee.setAmountPending(feeItemVo.getTotalAmount().doubleValue());
        }
        fee.setAmountPaid(null);
        fee.setAmountRefunded(0.00);
        fee.setAmountDeducted(0.00);
        fee.setBillStatus(PayConstants.BILLSTATUS_10);
        fee.setRefundStatus(PayConstants.REFUNDSTATUS_10);
        fee.setCloseStatus(PayConstants.YESORNO_Y);
        fee.setTenantId(student.getTenantId());
        fee.setDeleteFlag(PayConstants.DEL_STR_0);
        fee.setCreateDept(billBo.getCreateDept());
        fee.setCreateBy(billBo.getCreateBy());
        fee.setCreateTime(billBo.getCreateTime());
        fee.setUpdateBy(billBo.getUpdateBy());
        fee.setUpdateTime(fee.getCreateTime());
        fee.setIdNumber(student.getIdNumber());
        return fee;
    }

    private List<PayStudentFeeItem> buildPayStudentFeeItemFromStudent(StudentInfos student, PayStudentFee studentFee, List<PayStandardFeeItemDetailVo> feeItemDetailVos,GenerateBillBo billBo){
        List<PayStudentFeeItem> feeItems = new ArrayList<>();
        if(null==feeItemDetailVos || feeItemDetailVos.isEmpty()){
            return feeItems;
        }
        for(PayStandardFeeItemDetailVo detailVo:feeItemDetailVos){
            PayStudentFeeItem feeItem = new PayStudentFeeItem();
            feeItem.setStudentFeeId(studentFee.getId());
            feeItem.setBillNo(studentFee.getBillNo());
            if(null!=detailVo.getFeeItemConfigId()){
                feeItem.setFeeItemConfigId(detailVo.getFeeItemConfigId().intValue());
            }
            feeItem.setFeeItemConfigName(detailVo.getFeeItemConfigName());
            feeItem.setItemPrice(detailVo.getItemPrice().doubleValue());
            feeItem.setItemQuantity(1);
            feeItem.setTotalAmount(detailVo.getItemPrice().doubleValue());
            feeItem.setOrderNum(detailVo.getOrderNum());
            feeItem.setPayStatus(PayConstants.PAYSTATUS_10);
            if(null!=studentFee.getTenantId()){
                feeItem.setTenantId(studentFee.getTenantId().intValue());
            }
            feeItem.setDeleteFlag(PayConstants.DEL_STR_0);
            feeItem.setCreateDept(billBo.getCreateDept());
            feeItem.setCreateBy(billBo.getCreateBy());
            feeItem.setCreateTime(new Date());
            feeItem.setUpdateBy(billBo.getUpdateBy());
            feeItem.setUpdateTime(new Date());
            feeItems.add(feeItem);
        }
        return feeItems;
    }
    private Map<Integer,List<PayStudentFeeVo>> getPayStudentFeeVoMapByStudentId(List<StudentInfos> studentInfos){
        Map<Integer,List<PayStudentFeeVo>> result = new HashMap<>();
        if(null==studentInfos || studentInfos.isEmpty()){
            return result;
        }
        List<Long> studentIds = studentInfos.stream()
                .map(StudentInfos::getId)  // 调用 getStudentId() 方法
                .collect(Collectors.toList());
        List<PayStudentFeeVo> studentFeeVos = listByStudentIds(studentIds);
        if(null!=studentFeeVos && !studentFeeVos.isEmpty()){
            for(PayStudentFeeVo feeVo:studentFeeVos){
                if(!result.containsKey(feeVo.getStudentId())){
                    result.put(feeVo.getStudentId(),new ArrayList<>());
                }
                result.get(feeVo.getStudentId()).add(feeVo);
            }
        }
        return result;
    }
}
